package com.wannengbang.cloudleader.retorfit_manager;


import com.wannengbang.cloudleader.MyApplication;
import com.wannengbang.cloudleader.appconst.MethodType;
import com.wannengbang.cloudleader.appconst.URLConst;
import com.wannengbang.cloudleader.bean.BaseResponseBean;
import com.wannengbang.cloudleader.utils.SPManager;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * Time: 2019/7/15
 * Author: ZF
 * Description:
 */

public class RetrofitHelper {

    private volatile static RetrofitHelper mInstance = null;
    private Retrofit retrofit = null;
    private static long connectTimeout = 500;
    private static long writeTimeout = 500;
    private static long readTimeout = 500;
    private final BaseApi baseApi;

    public RetrofitHelper() {

        retrofit = new Retrofit.Builder()//
                .baseUrl(URLConst.BASE_URL)  //
                .client(getOkHttpClient())//
                .addConverterFactory(GsonConverterFactory.create())//
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //
                .build();

        baseApi = retrofit.create(BaseApi.class);

    }

    private OkHttpClient getOkHttpClient() {
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
        //显示日志
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
//        logInterceptor.setLevel(HttpLoggingInterceptor.Level.NONE);

        OkHttpClient.Builder clientBuild = new OkHttpClient.Builder();
        clientBuild.connectTimeout(connectTimeout, TimeUnit.SECONDS)//
                .writeTimeout(writeTimeout, TimeUnit.SECONDS)//
                //                .cache(new Cache(new File()))缓存
                .readTimeout(readTimeout, TimeUnit.SECONDS)//
                .addInterceptor(logInterceptor).retryOnConnectionFailure(true);
        clientBuild.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
        return clientBuild.build();
    }

    public static RetrofitHelper getInstance() {
        if (mInstance == null) {
            synchronized (RetrofitHelper.class) {
                if (mInstance == null) {
                    mInstance = new RetrofitHelper();
                }
            }
        }
        return mInstance;
    }

    public <T> void request(MethodType type, String url, ResponseObserver<? extends BaseResponseBean> observer) {
        Observable<ResponseBody> myObservable = null;
        if (MethodType.GET == type) {
            myObservable = baseApi.executeGet(url);
        } else if (MethodType.POST == type) {
            myObservable = baseApi.executePost(url);
        } else if (MethodType.PUT == type) {
            myObservable = baseApi.executePut(url);
        } else if (MethodType.DELETE == type) {
            myObservable = baseApi.executeDelete(url);
        }

        subscribeOn(myObservable, observer);
    }

    public <T> void request(MethodType type, String url, Map<String, Object> params, ResponseObserver<? extends BaseResponseBean> observer) {
        if (params == null || params.size() == 0) {
//            request(type, url, observer);
//            return;
            params = new HashMap<>();
        }
        //公共参数
        params.put("access_token", SPManager.getInstance().getToken());
        params.put("client_type", MyApplication.getClient_type());
        params.put("client_version", MyApplication.getClient_version());
        params.put("oem_app_id", MyApplication.getOem_app_id());

        Observable<ResponseBody> myObservable = null;
        if (MethodType.GET == type) {
            myObservable = baseApi.executeGet(url, params);
        } else if (MethodType.POST == type) {
            myObservable = baseApi.executePost(url, params);
        } else if (MethodType.PUT == type) {
            myObservable = baseApi.executePut(url, params);
        } else if (MethodType.DELETE == type) {
            myObservable = baseApi.executeDelete(url, params);
        }
        subscribeOn(myObservable, observer);

    }

    public <T> void uploadImg(MethodType type, String url, String fileUrl, ResponseObserver<? extends BaseResponseBean> observer) {
        File file = new File(fileUrl);
        // 创建 RequestBody，用于封装构建RequestBody
        // RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), file);
        RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), file);
        // MultipartBody.Part  和后端约定好Key，这里的partName是用file
        MultipartBody.Part body = MultipartBody.Part.createFormData("_file", file.getName(), requestFile);
        Observable<ResponseBody> myObservable = baseApi.uploadFile(url, body);
        subscribeOn(myObservable, observer);
    }

    public <T> void uploadFile(MethodType type, String url, MultipartBody.Part body, ResponseObserver<? extends BaseResponseBean> observer) {
        subscribeOn(baseApi.uploadFile(url, body), observer);
    }

    public <T> void uploadMultiAndFile(MethodType type, String url, List<MultipartBody.Part> files, ResponseObserver<? extends BaseResponseBean> observer) {
        subscribeOn(baseApi.uploadMultiAndFile(url, files), observer);
    }


    public void uploadMultiFile(MethodType type, String url, Map<String, RequestBody> maps, ResponseObserver<? extends BaseResponseBean> observer) {
        subscribeOn(baseApi.uploadMultiFile(url, maps), observer);
    }

    public void subscribeOn(Observable<ResponseBody> myObservable, ResponseObserver<? extends BaseResponseBean> observer) {

        if (myObservable == null) {
            return;
        }
        myObservable.subscribeOn(Schedulers.io())//
                .observeOn(AndroidSchedulers.mainThread())//
                .subscribe(observer);
    }


}
